import type { CanvasComponent } from '../stores/designStore';
import * as ejs from 'ejs';

// 声明全局nodeAPI类型
declare global {
  interface Window {
    nodeAPI: {
      fs: {
        readFileSync: (path: string, options?: any) => string | Buffer;
        writeFileSync: (path: string, data: string | Buffer, options?: any) => void;
        existsSync: (path: string) => boolean;
        mkdirSync: (path: string, options?: { recursive?: boolean }) => void;
      };
      path: {
        join: (...paths: string[]) => string;
        dirname: (path: string) => string;
        basename: (path: string, ext?: string) => string;
        extname: (path: string) => string;
      };
      process: {
        cwd: () => string;
        env: any;
        platform: string;
      };
    };
    electron: {
      ipcRenderer: {
        invoke: (channel: string, ...args: any[]) => Promise<any>;
        send: (channel: string, ...args: any[]) => void;
        on: (channel: string, func: (...args: any[]) => void) => () => void;
        once: (channel: string, func: (...args: any[]) => void) => void;
      };
    };
    electronAPI: {
      invoke: (channel: string, ...args: any[]) => Promise<any>;
      on: (channel: string, callback: (...args: any[]) => void) => () => void;
    };
  }
}

// 使用全局nodeAPI
const fs = window.nodeAPI?.fs;
const path = window.nodeAPI?.path;

interface ExportOptions {
  outputDir: string;
  productName: string;
  components: CanvasComponent[];
  elementPlusStyles?: string;
  elementPlusRuntime?: string;
  vueRuntime?: string;
  globalStyles?: string;
  componentStyles?: string;
  canvasSize?: { width: number; height: number };
}

/**
 * 导出 HTML 文件
 * @param options 导出选项
 * @returns Promise<void>
 */
export async function exportHtml(options: ExportOptions): Promise<void> {
  // 检查nodeAPI是否已加载
  if (!fs || !path) {
    throw new Error('Node.js API 未加载，请确保在 Electron 环境中运行');
  }

  const {
    outputDir,
    productName,
    components,
    elementPlusStyles,
    elementPlusRuntime,
    vueRuntime,
    globalStyles,
    componentStyles,
    canvasSize
  } = options;

  // 确保输出目录存在
  if (!fs.existsSync(outputDir)) {
    fs.mkdirSync(outputDir, { recursive: true });
  }

  // 读取模板文件
  const templatePath = path.join(__dirname, '../templates/miniblink.html.ejs');
  const template = fs.readFileSync(templatePath, 'utf-8');

  // 渲染模板
  const html = ejs.render(template, {
    productName,
    components,
    elementPlusStyles,
    elementPlusRuntime,
    vueRuntime,
    globalStyles,
    componentStyles,
    canvasSize
  });

  // 写入文件
  const outputPath = path.join(outputDir, 'index.html');
  fs.writeFileSync(outputPath, html, 'utf-8');
}

/**
 * 导出 Miniblink 项目
 * @param options 导出选项
 * @returns Promise<void>
 */
export async function exportMiniblinkProject(options: ExportOptions): Promise<void> {
  const {
    outputDir,
    productName,
    components,
    elementPlusStyles,
    elementPlusRuntime,
    vueRuntime,
    globalStyles,
    componentStyles
  } = options;

  // 创建项目目录结构
  const projectDir = path.join(outputDir, productName);
  const srcDir = path.join(projectDir, 'src');
  const publicDir = path.join(projectDir, 'public');

  // 创建目录
  fs.mkdirSync(projectDir, { recursive: true });
  fs.mkdirSync(srcDir, { recursive: true });
  fs.mkdirSync(publicDir, { recursive: true });

  // 导出 HTML 文件到 public 目录
  await exportHtml({
    ...options,
    outputDir: publicDir
  });

  // 创建 package.json
  const packageJson = {
    name: productName.toLowerCase().replace(/\s+/g, '-'),
    version: '1.0.0',
    description: `${productName} - Generated by Easy Window`,
    main: 'src/main.js',
    scripts: {
      start: 'electron .',
      build: 'electron-builder'
    },
    dependencies: {
      'element-plus': '^2.3.0',
      'vue': '^3.2.0'
    },
    devDependencies: {
      'electron': '^25.0.0',
      'electron-builder': '^24.0.0'
    }
  };

  fs.writeFileSync(
    path.join(projectDir, 'package.json'),
    JSON.stringify(packageJson, null, 2),
    'utf-8'
  );

  // 创建 README.md
  const readme = `# ${productName}

这是一个由 Easy Window 生成的桌面应用程序。

## 功能特点

- 基于 Vue 3 和 Element Plus 构建
- 支持 Miniblink 交互
- 响应式设计
- 现代化 UI 界面

## 开发说明

1. 安装依赖：
\`\`\`bash
npm install
\`\`\`

2. 启动开发服务器：
\`\`\`bash
npm start
\`\`\`

3. 构建应用：
\`\`\`bash
npm run build
\`\`\`

## Miniblink 集成

本应用支持通过 Miniblink 与其他语言（如 C#、易语言）进行交互。

### 事件通信

应用会触发以下事件：

- \`app:ready\`: 应用加载完成时触发
- \`component:click\`: 组件点击时触发
- \`component:change\`: 组件值变化时触发

### 示例代码

C# 示例：
\`\`\`csharp
using Miniblink;

public class MainForm : Form
{
    private WebView webView;

    public MainForm()
    {
        webView = new WebView();
        webView.LoadUrl("file:///path/to/index.html");
        
        // 监听事件
        webView.OnEvent += (sender, e) => {
            if (e.EventName == "app:ready")
            {
                Console.WriteLine("应用已就绪");
            }
            else if (e.EventName.StartsWith("component:"))
            {
                Console.WriteLine($"组件事件: {e.EventName}");
                Console.WriteLine($"组件数据: {e.EventData}");
            }
        };
    }
}
\`\`\`

易语言示例：
\`\`\`易语言
.版本 2

.程序集 窗口程序集

.子程序 _启动子程序, 整数型
.局部变量 浏览器, 整数型

浏览器 ＝ 创建浏览器 ("file:///path/to/index.html")
浏览器_注册事件 (浏览器, "app:ready", "应用就绪")
浏览器_注册事件 (浏览器, "component:click", "组件点击")
浏览器_注册事件 (浏览器, "component:change", "组件变化")

返回 (0)

.子程序 应用就绪, 整数型, 文本型 数据
调试输出 ("应用已就绪: " ＋ 数据)
返回 (0)

.子程序 组件点击, 整数型, 文本型 数据
调试输出 ("组件点击: " ＋ 数据)
返回 (0)

.子程序 组件变化, 整数型, 文本型 数据
调试输出 ("组件变化: " ＋ 数据)
返回 (0)
\`\`\`
`;

  fs.writeFileSync(
    path.join(projectDir, 'README.md'),
    readme,
    'utf-8'
  );

  // 创建主进程文件
  const mainJs = `const { app, BrowserWindow } = require('electron');
const path = require('path');

function createWindow() {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false
    }
  });

  win.loadFile(path.join(__dirname, '../public/index.html'));
}

app.whenReady().then(() => {
  createWindow();

  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) {
      createWindow();
    }
  });
});

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});`;

  fs.writeFileSync(
    path.join(srcDir, 'main.js'),
    mainJs,
    'utf-8'
  );
}

export class HTMLExporter {
  /**
   * 导出为HTML文件
   * @param param0 导出参数
   * @returns 导出结果
   */
  async export({ 
    components, 
    productName = 'UI Generated by Easy Window', 
    savePath,
    canvasSize = { width: 800, height: 600 }
  }: { 
    components: any[],
    productName?: string,
    savePath: string,
    canvasSize?: { width: number, height: number }
  }) {
    try {
      const fs = window.nodeAPI?.fs;
      const path = window.nodeAPI?.path;
      const ejs = require('ejs');
      
      if (!fs || !path) {
        throw new Error('无法访问文件系统API');
      }
      
      // 模板路径，使用 path.join 来确保跨平台兼容性
      const templatePath = path.join(__dirname, '../templates/html.ejs');
      const templateContent = fs.readFileSync(templatePath, 'utf-8');
      
      // 渲染模板
      const renderedHTML = ejs.render(templateContent, {
        components,
        productName,
        canvasSize
      });
      
      // 保存HTML文件
      fs.writeFileSync(savePath, renderedHTML, 'utf-8');
      
      console.log('导出HTML成功:', savePath);
      
      return {
        success: true,
        filePath: savePath
      };
    } catch (error) {
      console.error('导出HTML失败:', error);
      return {
        success: false,
        error
      };
    }
  }
} 